home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / diverses / cexpress / printer / justline.asm < prev    next >
Encoding:
Assembly Source File  |  1989-05-03  |  6.6 KB  |  212 lines

  1. ;void  justify_line(input_strg,return_string,remainder,line_len)
  2. ;  char  *input_strg,*return_string,*remainder;
  3. ;  int   line_len;
  4.  
  5.     EXTRN  _memory_model:byte
  6.     EXTRN  _remainder:byte
  7.  
  8. _TEXT    SEGMENT BYTE PUBLIC 'CODE'
  9.     ASSUME  CS:_TEXT
  10.     PUBLIC  _justify_line
  11. _justify_line proc near
  12.     push bp            
  13.     mov  bp,sp        
  14.     push di    
  15.     push si    
  16.     push ds            
  17.     cmp  _memory_model,0    ;near or far?
  18.     jle  begin        ;jump if near
  19.     inc  bp            ;else add 2 to BP
  20.     inc  bp            ;
  21. begin:    jmp  short Z2        ;jump over data
  22. remainder_seg dw ?
  23. remainder_ofs dw ?
  24. return_seg dw ?
  25. return_ofs dw ?
  26. num_write  db ?
  27. extra_space db ?
  28. line_len  dw ?
  29. Z2:    cmp  _memory_model,2    ;data near or far?
  30.     jb   Y2            ;jump if near    
  31.     les  di,dword ptr[bp+8] ;ES:DI pts to return string
  32.     lds  bx,dword ptr[bp+12] ;point DS:BX to remainder
  33.     mov  cs:remainder_seg,ds ;save for later
  34.     mov  cs:remainder_ofs,bx ;
  35.     mov  byte ptr ds:[bx],0    ;return null in remainder if error
  36.     lds  si,dword ptr[bp+4]    ;point DS:SI to Strg
  37.     mov  ax,[bp+16]        ;line_len value to AX
  38.     jmp  short X2        ;jump ahead
  39. Y2:    mov  ax,ds        ;NEAR case
  40.     mov  es,ax        ;
  41.     mov  di,[bp+6]        ;
  42.     mov  bx,[bp+8]        ;
  43.     mov  cs:remainder_seg,ds ;save for later
  44.     mov  cs:remainder_ofs,bx ;
  45.     mov  byte ptr ds:[bx],0    ;return null in remainder if error
  46.     mov  si,[bp+4]        ;
  47.     mov  ax,[bp+10]        ;        
  48. X2:    mov  byte ptr es:[di],0    ;return null in return_strg if error
  49.     mov  cs:return_seg,es    ;keep address for later
  50.     mov  cs:return_ofs,di    ;
  51.     mov  cs:line_len,ax    ;keep line length for later
  52.     or   ax,ax        ;test for null line_length
  53.     jz   U2            ;quit if null
  54.     push si            ;get length of input string
  55.     sub  cx,cx        ;clear CX
  56. W2:    cmp  byte ptr[si],0    ;
  57.     je   V2            ;
  58.     inc  cx            ;
  59.     inc  si            ;
  60.     jmp  short W2        ;
  61. V2:    pop  si            ;
  62.     dec  si            ;
  63.     or   cx,cx        ;test if null input
  64.     jnz  B1            ;
  65. U2:    jmp  B2            ;quit if null
  66. B1:    cmp  byte ptr[si+1],32 ;nxt char a space?
  67.     jne  D1            ;jump ahead if not
  68.     cmp  byte ptr[si+3],32 ;3rd char a space?
  69.     jne  C1            ;jump ahead if not
  70.     cmp  byte ptr[si+2],32 ;2nd char a space?
  71.     je   D1            ;don't del spcs if so
  72. C1:    dec  cl            ;dec string len ctr
  73.     inc  si            ;forward BP to elim char
  74.     jmp  short B1        ;go check for another spc
  75. D1:    mov  dx,cx        ;copy strg len to DX
  76.     sub  bx,bx        ;use BX as ptr to string
  77. E1:    inc  bx            ;forward string pointer
  78.     cmp  byte ptr[bx][si],128 ;high end of codes
  79.     jb   F1            ;jump if not ctrl code
  80.     cmp  byte ptr[bx][si],159 ;low end of codes
  81.     ja   F1            ;jump if not ctrl code
  82.     dec  dx            ;dec string length ctr
  83. F1:    loop E1            ;go count next char
  84.     push bx            ;save string length
  85.     cmp  dx,ax        ;cmp strg len to linelen
  86.     ja   G1            ;jump ahead if longer
  87.     pop  cx            ;balance stack for jmp
  88.     mov  cx,bx        ;mov string len to CX
  89.     sub  ax,ax        ;AX=0 flags short string
  90.     jmp  short N1        ;go set string for return
  91. G1:    mov  cx,ax        ;linelen to CX
  92.     sub  ax,ax        ;AX holds spc positions
  93.     sub  dh,dh        ;clear DH to count spaces
  94.     inc  cx            ;count one further
  95.     sub  bx,bx        ;pt SI to start of strg
  96. H1:    inc  bx            ;forward string pointer
  97.     cmp  byte ptr[bx][si],128 ;low end of codes
  98.     jb   I1            ;jump ahead if not
  99.     cmp  byte ptr[bx][si],159 ;high end of codes
  100.     ja   I1            ;jump ahead if not
  101.     jmp  short H1        ;else don't count it
  102. I1:    cmp  byte ptr[bx][si],32 ;spc char?
  103.     jne  J1            ;jump ahead if not
  104.     mov  ax,bx        ;else save spc position
  105.     inc  dh            ;inc count of spaces
  106. J1:    loop H1            ;go do next char in strg
  107.     cmp  ax,0        ;no spaces at all?
  108.     je   K1            ;jump ahead if so
  109.     mov  bx,ax        ;point SI to last spc
  110.     jmp  short L1        ;jump ahead
  111. K1:    mov  ax,bx        ;set string pointer
  112.     dec  bx            ;set back 1
  113. L1:    pop  cx            ;string length to CX
  114.     sub  cx,bx        ;remainder length
  115.     push ax            ;point ES:DI to remainder
  116.     mov  ax,cs:remainder_seg ;point to remainder
  117.     mov  es,ax         ;
  118.     mov  di,cs:remainder_ofs ;
  119.     pop  ax            ;
  120.     inc  bx            ;remainder ptr to 1st chr
  121.     dec  di            ;adjust for loop ahead
  122. M1:    inc  di            ;forward remainder ptr
  123.     mov  dl,[bx][si]    ;get char from end of str
  124.     mov  es:[di],dl        ;place in remainder
  125.     inc  bx            ;forward string ptr
  126.     loop M1            ;go get next char
  127.     mov  cx,ax        ;return string length
  128.     dec  cx            ;adjust
  129. N1:    sub  bx,bx        ;clear string pointer
  130.     or   ax,ax        ;test for zero length
  131.     jnz  P1            ;skip loop if zero
  132.     dec  di            ;adjust for loop ahead
  133. O1:    inc  bx            ;forward strg ptr
  134.     inc  di            ;forward return ptr
  135.     mov  dl,[bx][si]    ;get char from strg
  136.     mov  es:[di],dl        ;set it for return
  137.     loop O1            ;go get next char
  138.     mov  byte ptr es:[di+2],0 ;set terminator
  139.     jmp  B2            ;quit routine
  140. P1:    dec  dh            ;adjust num spc positions
  141.     mov  dl,dh        ;move to DL
  142.     sub  dh,dh        ;DX holds num spc pos
  143.     mov  ax,cs:line_len    ;fetch line length
  144.     push cx            ;save string length
  145. Q1:    inc  bx            ;for ea byte of string..
  146.     cmp  byte ptr[bx][si],128 ;low end of codes
  147.     jb   R1            ;jump ahead if not code
  148.     cmp  byte ptr[bx][si],159 ;high end of codes
  149.     ja   R1            ;jump ahead if not code
  150.     inc  ax            ;else inc ctrl code ctr
  151. R1:    loop Q1            ;go check next char
  152.     pop  cx            ;restore string length
  153.     mov  di,ax        ;DI=LineLen+num ctrl codes
  154.     sub  di,cx        ;DI=num extra spaces
  155. S1:    cmp  di,dx        ;div by num spc positions
  156.     jb   T1            ;leave loop when finished
  157.     inc  ah            ;inc result
  158.     sub  di,dx        ;adjust dividend
  159.     jmp  short S1        ;loop
  160. T1:    mov  bx,di        ;make high and low available
  161.     push ax            ;for ES:DI to return string
  162.     mov  ax,cs:return_seg    ;
  163.     mov  es,ax        ;
  164.     mov  di,cs:return_ofs    ;
  165.     pop  ax            ;
  166.     dec  di            ;
  167.     mov  bh,ah        ;num spc to add at ea pos
  168.     mov  dh,bl        ;copy remainder to DH
  169.     sub  dl,bl        ;spc positions-remainder
  170.     mov  bl,dl        ;num pos to NOT wrt extra
  171.     mov  al,dh        ;copy remainder in AL
  172.     shr  dh,1        ;divide remainder by 2
  173.     sub  al,dh        ;(AL=right)
  174.     mov  cs:num_write,bh    ;save values
  175.     mov  cs:extra_space,bl    ;
  176.     sub  bx,bx        ;pointer back to start of string
  177. U1:    inc  bx            ;forward string ptr
  178.     inc  di            ;forward return strg ptr
  179.     mov  dl,[bx][si]    ;get char from string
  180.     cmp  dl,32        ;check for space char
  181.     jne  A2            ;jump ahead if not spc
  182. V1:    or   ah,ah        ;AH=extra spc at each pos
  183.     jz   W1            ;jump ahead if none
  184.     dec  ah            ;else count down
  185.     mov  es:[di],dl        ;write a space
  186.     inc  di            ;forward ret strg ptr
  187.     jmp  short V1        ;go chk for another
  188. W1:    mov  ah,cs:num_write    ;
  189.     or   dh,dh        ;DL=extra spc on left
  190.     jz   X1            ;jump ahead if done
  191.     dec  dh            ;else dec left spc ctr
  192.     jmp  short Y1        ;go write the extra space
  193. X1:    cmp  byte ptr cs:extra_space,0
  194.     jne  Z1            ;
  195. Y1:    mov  es:[di],dl        ;else write spc on right
  196.     inc  di            ;forward string ptr
  197.     jmp  short A2        ;jump ahead
  198. Z1:    dec  cs:extra_space    ;dec extra space counter
  199. A2:    mov  es:[di],dl        ;set it for return
  200.     loop U1            ;go do next char
  201. B2:    pop  ds            ;
  202.     pop  si            ;
  203.     pop  di            ;
  204.     pop  bp            ;
  205.     cmp  _memory_model,0    ;quit
  206.     jle  quit        ;
  207.     db   0CBh        ;RET far
  208. quit:    ret            ;RET near
  209. _justify_line endp
  210. _TEXT    ENDS
  211.     END
  212.